﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.IO;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;

//using System.Numerics;

namespace BitmapFilter
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "*.jpg,*.jpeg,*.bmp,*.gif,*.ico,*.png,*.tif,*.wmf|*.jpg;*.jpeg;*.bmp;*.gif;*.ico;*.png;*.tif;*.wmf";
            openFileDialog.ShowDialog();//打开文件
            Bitmap bitmap = (Bitmap)Bitmap.FromFile(openFileDialog.FileName);

            string fileName = openFileDialog.FileName;
            FileInfo f = new FileInfo(fileName);//新建一个文件
            this.label1.Text = f.Name;

            /*******************rgb2gray*********************************************************************************/

            Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            // Lock the bitmap's bits. 
            //转成24rgb颜色 24色就是由r g b, 三个颜色, 每个颜色各用一字节(8位)表示亮度
            BitmapData bmpData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

            int iStride = bmpData.Stride; //图片一行象素所占用的字节  

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            int iBytes = iStride * bitmap.Height;
            byte[] rgbValues = new byte[iBytes];

            // Copy RGB values into the Array
            Marshal.Copy(ptr, rgbValues, 0, iBytes);

            for (int y = 0; y < bmpData.Height; ++y)
            {
                for (int x = 0; x < bmpData.Width; ++x)
                {
                    //图像(x, y)坐标坐标中第1个像素中rgbValues中的索引位置(这儿x,y是从0开始记的)
                    //rgbValues每行是扫描宽个字节, 不是bitmap.Width * 3
                    int iThird = iStride * y + 3 * x;
                    byte avg = (byte)((rgbValues[iThird] + rgbValues[iThird + 1] + rgbValues[iThird + 2]) / 3);//转化成灰度
                    rgbValues[iThird] = avg;
                    rgbValues[iThird + 1] = avg;
                    rgbValues[iThird + 2] = avg;
                }
            }
            // copy到原来图像中
            Marshal.Copy(rgbValues, 0, ptr, rgbValues.Length);
            // Unlock the bits.
            bitmap.UnlockBits(bmpData);
            pictureBox1.Image = bitmap;//显示图片
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (comboBox1.SelectedItem == null)
            {
                return;
            }
            else if (comboBox1.SelectedItem == "添加噪声")
            {
                Bitmap bitmap = new Bitmap(pictureBox1.Image);
                Bitmap retmap = AddNoise(bitmap, bitmap.Width, bitmap.Height);
                pictureBox2.Image = retmap;//显示图片
            }
            else if (comboBox1.SelectedItem == "高斯滤波")
            {
                Bitmap bitmap = new Bitmap(pictureBox1.Image);
                Bitmap retmap = GaussianFilter(bitmap, bitmap.Width, bitmap.Height);
                pictureBox2.Image = retmap;//显示图片
            }
            else if (comboBox1.SelectedItem == "阈值平均法")
            {
                Bitmap bitmap = new Bitmap(pictureBox1.Image);
                Bitmap retmap = ThresholdAVG(bitmap, bitmap.Width, bitmap.Height, threshold);
                pictureBox2.Image = retmap;//显示图片
            }
            else if (comboBox1.SelectedItem == "中值滤波法")
            {
                Bitmap bitmap = new Bitmap(pictureBox1.Image);
                Bitmap retmap = MedianFilter(bitmap, bitmap.Width, bitmap.Height);
                pictureBox2.Image = retmap;//显示图片
            }
            else if (comboBox1.SelectedItem == "均值滤波")
            {
                Bitmap bitmap = new Bitmap(pictureBox1.Image);
                Bitmap retmap = AverageFilter(bitmap, bitmap.Width, bitmap.Height);
                pictureBox2.Image = retmap;//显示图片
            }
            else if (comboBox1.SelectedItem == "拉普拉斯锐化法")
            {
                Bitmap bitmap = new Bitmap(pictureBox1.Image);
                Bitmap retmap = LaplacianSharpen(bitmap, bitmap.Width, bitmap.Height);
                pictureBox2.Image = retmap;//显示图片
            }
            else if (comboBox1.SelectedItem == "伪彩色增强")
            {
                Bitmap bitmap = new Bitmap(pictureBox1.Image);
                Bitmap retmap = gcTrans_1(bitmap, bitmap.Width, bitmap.Height);
                pictureBox2.Image = retmap;//显示图片
            }
        }

        //添加噪声
        private Bitmap AddNoise(Bitmap basemap, int width, int height)
        {
            Bitmap retmap = new Bitmap(basemap, width, height);
            Random rand = new Random();
            double Pa = rand.Next(10);
            Pa = 0.01 * Pa;
            double Pb = rand.Next(10);
            Pb = 0.01 * Pb;
            double P = Pb / (1 - Pa);
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    int gray;
                    int noise = 1;
                    double probility = rand.NextDouble();
                    if (probility < Pa)
                    {
                        noise = 255;//有Pa概率 噪声设为最大值  
                    }
                    else
                    {
                        double temp = rand.NextDouble();
                        if (temp < Pb)//有1 - Pa的几率到达这里，再乘以 P ，刚好等于Pb  
                            noise = 0;
                    }
                    if (noise != 1)
                    {
                        gray = noise;
                    }
                    else gray = basemap.GetPixel(j, i).R;
                    Color color = Color.FromArgb(gray, gray, gray);
                    retmap.SetPixel(j, i, color);
                }
            }
            return retmap;
        }


        //高斯滤波
        private Bitmap GaussianFilter(Bitmap basemap, int width, int height)
        {
            Bitmap retmap = new Bitmap(basemap, width, height);
            Color c1 = new Color();
            Color c2 = new Color();
            Color c3 = new Color();
            Color c4 = new Color();
            Color c5 = new Color();
            Color c6 = new Color();
            Color c7 = new Color();
            Color c8 = new Color();
            Color c9 = new Color();
            int rr, r1, r2, r3, r4, r5, r6, r7, r8, r9, i, j, fxr;
            for (i = 1; i <= width - 2; i++)
            {
                for (j = 1; j <= height - 2; j++)
                {
                    //提取9个格子的灰度值
                    c1 = basemap.GetPixel(i, j - 1);
                    c2 = basemap.GetPixel(i - 1, j);
                    c3 = basemap.GetPixel(i, j);
                    c4 = basemap.GetPixel(i + 1, j);
                    c5 = basemap.GetPixel(i, j + 1);
                    c6 = basemap.GetPixel(i - 1, j - 1);
                    c7 = basemap.GetPixel(i - 1, j + 1);
                    c8 = basemap.GetPixel(i + 1, j - 1);
                    c9 = basemap.GetPixel(i + 1, j + 1);
                    r1 = c1.R;
                    r2 = c2.R;
                    r3 = c3.R;
                    r4 = c4.R;
                    r5 = c5.R;
                    r6 = c6.R;
                    r7 = c7.R;
                    r8 = c8.R;
                    r9 = c9.R;
                    //求高斯滤波后的值
                    fxr = (r6 + r7 + r8 + r9 + 2 * r1 + 2 * r2 + 2 * r4 + 2 * r5 + 4 * r3) / 16;
                    rr = fxr;
                    if (rr < 0) rr = 0;
                    if (rr > 255) rr = 255;
                    Color cc = Color.FromArgb(rr, rr, rr);
                    retmap.SetPixel(i, j, cc);
                }
            }
            return retmap;
        }
        //中值滤波
        private Bitmap MedianFilter(Bitmap basemap, int width, int height)
        {
            Bitmap retmap = new Bitmap(basemap, width, height);
            Color c1 = new Color();
            Color c2 = new Color();
            Color c3 = new Color();
            Color c4 = new Color();
            Color c5 = new Color();
            Color c6 = new Color();
            Color c7 = new Color();
            Color c8 = new Color();
            Color c9 = new Color();
            int[] r = new int[9];
            int rr, i, j, tr, temp, m, n;
            for (i = 1; i <= width - 2; i++)
            {
                for (j = 1; j <= height - 2; j++)
                {
                    //提取9个格子的灰度值
                    c1 = basemap.GetPixel(i, j - 1);
                    c2 = basemap.GetPixel(i - 1, j);
                    c3 = basemap.GetPixel(i, j);
                    c4 = basemap.GetPixel(i + 1, j);
                    c5 = basemap.GetPixel(i, j + 1);
                    c6 = basemap.GetPixel(i - 1, j - 1);
                    c7 = basemap.GetPixel(i - 1, j + 1);
                    c8 = basemap.GetPixel(i + 1, j - 1);
                    c9 = basemap.GetPixel(i + 1, j + 1);
                    r[0] = c1.R;
                    r[1] = c2.R;
                    r[2] = c3.R;
                    r[3] = c4.R;
                    r[4] = c5.R;
                    r[5] = c6.R;
                    r[6] = c7.R;
                    r[7] = c8.R;
                    r[8] = c9.R;
                    //9个格子灰度值冒泡排序
                    for (m = 0; m < 8; m++)
                    {
                        for (n = m + 1; n < 9; n++)
                        {
                            if (r[m] > r[n])
                            {
                                // 互换  
                                temp = r[m];
                                r[m] = r[n];
                                r[n] = temp;
                            }
                        }
                    }
                    // 计算中值 
                    tr = r[4];
                    rr = tr;
                    if (rr < 0) rr = 0;
                    if (rr > 255) rr = 255;
                    Color cc = Color.FromArgb(rr, rr, rr);
                    retmap.SetPixel(i, j, cc);
                }
            }
            return retmap;
        }

        //均值滤波
        private Bitmap AverageFilter(Bitmap basemap, int width, int height)
        {
            Bitmap retmap = new Bitmap(basemap, width, height);
            Color c1 = new Color();
            Color c2 = new Color();
            Color c3 = new Color();
            Color c4 = new Color();
            Color c5 = new Color();
            Color c6 = new Color();
            Color c7 = new Color();
            Color c8 = new Color();
            Color c9 = new Color();
            int rr, r1, r2, r3, r4, r5, r6, r7, r8, r9, i, j, fxr;
            for (i = 1; i <= width - 2; i++)
            {
                for (j = 1; j <= height - 2; j++)
                {
                    //提取9个格子的灰度值
                    c1 = basemap.GetPixel(i, j - 1);
                    c2 = basemap.GetPixel(i - 1, j);
                    c3 = basemap.GetPixel(i, j);
                    c4 = basemap.GetPixel(i + 1, j);
                    c5 = basemap.GetPixel(i, j + 1);
                    c6 = basemap.GetPixel(i - 1, j - 1);
                    c7 = basemap.GetPixel(i - 1, j + 1);
                    c8 = basemap.GetPixel(i + 1, j - 1);
                    c9 = basemap.GetPixel(i + 1, j + 1);
                    r1 = c1.R;
                    r2 = c2.R;
                    r3 = c3.R;
                    r4 = c4.R;
                    r5 = c5.R;
                    r6 = c6.R;
                    r7 = c7.R;
                    r8 = c8.R;
                    r9 = c9.R;
                    fxr = (r1 + r2 + r3 + r4 + r5 + r6 + r7 + r8 + r9) / 9;//9个格子的平均值
                    rr = fxr;
                    if (rr < 0) rr = 0;
                    if (rr > 255) rr = 255;
                    Color cc = Color.FromArgb(rr, rr, rr);
                    retmap.SetPixel(i, j, cc);
                }
            }
            return retmap;
        }

        //设定一个阈值
        private static int threshold = 90;
        //阈值平均
        private Bitmap ThresholdAVG(Bitmap basemap, int width, int height, int threshold)
        {

            Bitmap retmap = new Bitmap(basemap, width, height);
            Color c1 = new Color();
            Color c2 = new Color();
            Color c3 = new Color();
            Color c4 = new Color();
            Color c5 = new Color();
            Color c6 = new Color();
            Color c7 = new Color();
            Color c8 = new Color();
            Color c9 = new Color();
            int rr, r1, r2, r3, r4, r5, r6, r7, r8, r9, i, j, fxr;
            for (i = 1; i <= width - 2; i++)
            {
                for (j = 1; j <= height - 2; j++)
                {
                    //提取9个格子的灰度值
                    c1 = basemap.GetPixel(i, j - 1);
                    c2 = basemap.GetPixel(i - 1, j);
                    c3 = basemap.GetPixel(i, j);
                    c4 = basemap.GetPixel(i + 1, j);
                    c5 = basemap.GetPixel(i, j + 1);
                    c6 = basemap.GetPixel(i - 1, j - 1);
                    c7 = basemap.GetPixel(i - 1, j + 1);
                    c8 = basemap.GetPixel(i + 1, j - 1);
                    c9 = basemap.GetPixel(i + 1, j + 1);
                    r1 = c1.R;
                    r2 = c2.R;
                    r3 = c3.R;
                    r4 = c4.R;
                    r5 = c5.R;
                    r6 = c6.R;
                    r7 = c7.R;
                    r8 = c8.R;
                    r9 = c9.R;
                    //求平均值
                    fxr = (r1 + r2 + r3 + r4 + r5 + r6 + r7 + r8 + r9) / 9;
                    rr = fxr;

                    if (rr < 0) rr = 0;
                    if (rr > 255) rr = 255;
                    Color cc = Color.FromArgb(rr, rr, rr);
                    Color ab = Color.FromArgb(basemap.GetPixel(i, j).R, basemap.GetPixel(i, j).R, basemap.GetPixel(i, j).R);
                    //判断是否大于阈值
                    if (Math.Abs(rr - basemap.GetPixel(i, j).R) > threshold)
                        retmap.SetPixel(i, j, cc);
                    else
                        retmap.SetPixel(i, j, ab);
                    //retmap.SetPixel(i, j, cc);
                }
            }
            return retmap;
        }

        //拉普拉斯锐化
        //下面两种都可以
        //第一种可以处理rgb真彩图
        //第二种只能处理灰度图，
        //两种原理相同，用a=1的拉普拉斯模板处理

        //public Bitmap LaplacianSharpen(Bitmap basemap, int width, int height)
        //{
        //    Bitmap retmap = new Bitmap(basemap, width, height);
        //    //拉普拉斯模板
        //    int[] Laplacian = { -1, -1, -1, -1, 9, -1, -1, -1, -1 };
        //    for (int i = 1; i < width - 1; i++)//遍历像素
        //        for (int j = 1; j < height - 1; j++)
        //        {
        //            int tem_r = 0, tem_g = 0, tem_b = 0, tem_index = 0;
        //            for (int c = -1; c <= 1; c++)
        //                for (int r = -1; r <= 1; r++)
        //                {
        //                    //处理九宫格的每个像素的rgb指
        //                    Color tem_color = basemap.GetPixel(i + r, j + c);
        //                    tem_r += tem_color.R * Laplacian[tem_index];
        //                    tem_g += tem_color.G * Laplacian[tem_index];
        //                    tem_b += tem_color.B * Laplacian[tem_index];
        //                    tem_index++;//
        //                }
        //            tem_r = tem_r > 255 ? 255 : tem_r;
        //            tem_r = tem_r < 0 ? 0 : tem_r;
        //            tem_g = tem_g > 255 ? 255 : tem_g;
        //            tem_g = tem_g < 0 ? 0 : tem_g;
        //            tem_b = tem_b > 255 ? 255 : tem_b;
        //            tem_b = tem_b < 0 ? 0 : tem_b;
        //            retmap.SetPixel(i - 1, j - 1, Color.FromArgb(tem_r, tem_g, tem_b));
        //        }
        //    return retmap;
        //}
        private Bitmap LaplacianSharpen(Bitmap basemap, int width, int height)
        {
            Bitmap retmap = new Bitmap(basemap, width, height);
            //拉普拉斯模板
            //a=1
            int[] Laplacian = { -1, -1, -1, -1, 9, -1, -1, -1, -1 };
            Color pixel = new Color();
            int i, j, index;

            for (i = 1; i <= width - 2; i++)
            {
                for (j = 1; j <= height - 2; j++)
                {
                    int r = 0;
                    index = 0;
                    for (int col = -1; col <= 1; col++)
                    {
                        for (int row = -1; row <= 1; row++)
                        {
                            pixel = basemap.GetPixel(i + row, j + col);
                            r += pixel.R * Laplacian[index];
                            index++;
                        }
                    }
                    if (r < 0) r = 0;
                    if (r > 255) r = 255;
                    Color cc = Color.FromArgb(r, r, r);
                    retmap.SetPixel(i, j, cc);
                }
            }
            return retmap;
        }

        private Bitmap gcTrans_1(Bitmap basemap, int width, int height)
        {
            Bitmap retmap = new Bitmap(basemap, width, height);
            Color pixel = new Color();
            int i, j;
            for (i = 1; i <= width - 1; i++)
            {
                for (j = 1; j <= height - 1; j++)
                {
                    int r = 0, g = 0, b = 0;
                    pixel = basemap.GetPixel(i, j);
                    r = pixel.R;
                    //按灰度级分层
                    //填充不同颜色
                    if (r < 64)
                    {
                        r = 0;
                        g = (4 * r);
                        b = 255;
                    }
                    else if (r < 128)
                    {
                        r = 0;
                        g = 255;
                        b = (-4 * r + 2 * 255);
                    }
                    else if (r < 192)
                    {
                        r = (4 * r - 2 * 255);
                        g = 255;
                        b = 0;
                    }
                    else
                    {
                        r = 255;
                        g = (-4 * r + 4 * 255);
                        b = 0;
                    }
                    r = r > 255 ? 255 : r;
                    r = r < 0 ? 0 : r;
                    g = g > 255 ? 255 : g;
                    g = g < 0 ? 0 : g;
                    b = b > 255 ? 255 : b;
                    b = b < 0 ? 0 : b;
                    retmap.SetPixel(i, j, Color.FromArgb(r, g, b));
                }
            }
            return retmap;
        }

    }
}
